import React, { useState, useCallback } from 'react';
import ReactFlow, {
  Node,
  Edge,
  Controls,
  Background,
  useNodesState,
  useEdgesState,
  addEdge,
  Connection,
  Panel,
  NodeTypes,
  NodeProps,
} from 'reactflow';
import 'reactflow/dist/style.css';
import { Button, Modal, Form, Input, Select, message } from 'antd';
import { FlowPathNodeType, FlowPathNode, FlowPathNodeStatus } from '../store/flowpathTypes';

interface NodeEditorProps {
  nodes: FlowPathNode[];
  edges: { source: string; target: string; condition?: string }[];
  onChange: (nodes: FlowPathNode[], edges: { source: string; target: string; condition?: string }[]) => void;
}

// 自定义节点类型
const CustomNode: React.FC<NodeProps> = ({ data }) => (
  <div style={{ padding: 10, border: '1px solid #ddd', borderRadius: 5, background: '#fff' }}>
    <div>{data.label}</div>
  </div>
);

const nodeTypes: NodeTypes = {
  default: CustomNode,
};

const NodeEditor: React.FC<NodeEditorProps> = ({ nodes: initialNodes, edges: initialEdges, onChange }) => {
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes.map(node => ({
    id: node.id,
    type: 'default',
    position: node.position,
    data: { label: node.name, ...node },
  })));
  
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges.map(edge => ({
    id: `${edge.source}-${edge.target}`,
    source: edge.source,
    target: edge.target,
    label: edge.condition || '',
    type: 'default',
  })));

  const [isModalVisible, setIsModalVisible] = useState(false);
  const [editingNode, setEditingNode] = useState<FlowPathNode | null>(null);
  const [form] = Form.useForm();

  const onConnect = useCallback(
    (params: Connection) => {
      if (!params.source || !params.target) return;
      
      const newEdge = {
        ...params,
        id: `${params.source}-${params.target}`,
        label: '',
        type: 'default',
      };
      
      setEdges((eds) => addEdge(newEdge, eds));
      
      const updatedNodes = nodes.map(node => ({
        id: node.id,
        type: node.data.type,
        name: node.data.label,
        description: node.data.description,
        config: node.data.config,
        status: node.data.status,
        nextNodes: node.data.nextNodes,
        position: node.position,
      }));

      const updatedEdges = edges.map(edge => ({
        source: edge.source,
        target: edge.target,
        condition: typeof edge.label === 'string' ? edge.label : undefined,
      }));

      updatedEdges.push({
        source: params.source,
        target: params.target,
        condition: undefined,
      });

      onChange(updatedNodes, updatedEdges);
    },
    [nodes, edges, onChange]
  );

  const handleAddNode = () => {
    setEditingNode(null);
    form.resetFields();
    setIsModalVisible(true);
  };

  const handleEditNode = (nodeId: string) => {
    const node = nodes.find(n => n.id === nodeId);
    if (node) {
      setEditingNode({
        id: node.id,
        type: node.data.type,
        name: node.data.label,
        description: node.data.description,
        config: node.data.config,
        status: node.data.status,
        nextNodes: node.data.nextNodes,
        position: node.position,
      });
      form.setFieldsValue({
        type: node.data.type,
        name: node.data.label,
        description: node.data.description,
        config: JSON.stringify(node.data.config),
      });
      setIsModalVisible(true);
    }
  };

  const handleSaveNode = () => {
    form.validateFields().then(values => {
      const newNode: FlowPathNode = {
        id: editingNode?.id || `node-${Date.now()}`,
        type: values.type,
        name: values.name,
        description: values.description,
        config: values.config ? JSON.parse(values.config) : {},
        status: FlowPathNodeStatus.PENDING,
        nextNodes: [],
        position: editingNode?.position || { x: 100, y: 100 },
      };

      if (editingNode) {
        const newNodes = nodes.map(node => 
          node.id === editingNode.id 
            ? {
                ...node,
                data: { ...node.data, ...newNode },
              }
            : node
        );
        setNodes(newNodes);
        onChange(
          newNodes.map(node => ({
            id: node.id,
            type: node.data.type,
            name: node.data.label,
            description: node.data.description,
            config: node.data.config,
            status: node.data.status,
            nextNodes: node.data.nextNodes,
            position: node.position,
          })),
          edges.map(edge => ({
            source: edge.source,
            target: edge.target,
            condition: typeof edge.label === 'string' ? edge.label : undefined,
          }))
        );
      } else {
        const newNodes = [...nodes, {
          id: newNode.id,
          type: 'default',
          position: newNode.position,
          data: { label: newNode.name, ...newNode },
        }];
        setNodes(newNodes);
        onChange(
          newNodes.map(node => ({
            id: node.id,
            type: node.data.type,
            name: node.data.label,
            description: node.data.description,
            config: node.data.config,
            status: node.data.status,
            nextNodes: node.data.nextNodes,
            position: node.position,
          })),
          edges.map(edge => ({
            source: edge.source,
            target: edge.target,
            condition: typeof edge.label === 'string' ? edge.label : undefined,
          }))
        );
      }

      setIsModalVisible(false);
      message.success('节点保存成功');
    });
  };

  const handleDeleteNode = (nodeId: string) => {
    const newNodes = nodes.filter(node => node.id !== nodeId);
    const newEdges = edges.filter(
      edge => edge.source !== nodeId && edge.target !== nodeId
    );
    setNodes(newNodes);
    setEdges(newEdges);
    onChange(
      newNodes.map(node => ({
        id: node.id,
        type: node.data.type,
        name: node.data.label,
        description: node.data.description,
        config: node.data.config,
        status: node.data.status,
        nextNodes: node.data.nextNodes,
        position: node.position,
      })),
      newEdges.map(edge => ({
        source: edge.source,
        target: edge.target,
        condition: typeof edge.label === 'string' ? edge.label : undefined,
      }))
    );
    message.success('节点删除成功');
  };

  return (
    <div style={{ height: 600 }}>
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        onConnect={onConnect}
        nodeTypes={nodeTypes}
        fitView
      >
        <Background />
        <Controls />
        <Panel position="top-right">
          <Button type="primary" onClick={handleAddNode}>
            添加节点
          </Button>
        </Panel>
      </ReactFlow>

      <Modal
        title={editingNode ? '编辑节点' : '添加节点'}
        open={isModalVisible}
        onOk={handleSaveNode}
        onCancel={() => setIsModalVisible(false)}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="type"
            label="节点类型"
            rules={[{ required: true, message: '请选择节点类型' }]}
          >
            <Select placeholder="请选择节点类型">
              {Object.values(FlowPathNodeType).map(type => (
                <Select.Option key={type} value={type}>
                  {type}
                </Select.Option>
              ))}
            </Select>
          </Form.Item>

          <Form.Item
            name="name"
            label="节点名称"
            rules={[{ required: true, message: '请输入节点名称' }]}
          >
            <Input placeholder="请输入节点名称" />
          </Form.Item>

          <Form.Item
            name="description"
            label="节点描述"
          >
            <Input.TextArea placeholder="请输入节点描述" />
          </Form.Item>

          <Form.Item
            name="config"
            label="节点配置"
          >
            <Input.TextArea
              placeholder="请输入节点配置（JSON格式）"
              rows={4}
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default NodeEditor;